home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.mactech.com 2010
/
ftp.mactech.com.tar
/
ftp.mactech.com
/
machack
/
Hacks96
/
RoasterJavaWAHTTPCGI.sit
/
Roaster-Java-WA-HTTP-CGI hack
/
Protect WA plugin
/
Protect.cp
< prev
next >
Wrap
Text File
|
1996-06-22
|
18KB
|
646 lines
// Sample field protection plugin, using the industry standart ROT13 algorithm.
#include "ArrangeCallbacks.h"
#include "PluginLibrary.h"
#include <Dialogs.h>
#include <StandardFile.h>
#include <string.h>
#include <Folders.h>
#include <TextUtils.h>
#include <Resources.h>
#include <AppleEvents.h>
#include <PLStringFuncs.h> /* some special string handling stuff */
#if defined (__MWERKS__) && defined (PLUGIN_GLOBALS)
#include "A4Stuff.h"
#endif
#define ModuleRsrcID -0x8000
#define OurModuleID 0x72300000 //Unique module ID assigned by Phil Meyer
//#define OurModuleID 0x70001513 // Unique module ID; replace with a value
// obtained from Common Knowledge.
#define baseCmdCode OurModuleID
#define pluginName "Protect" // controls our name in the About menu
#define aboutCmdCode (baseCmdCode + 0)
#define reformatText (baseCmdCode + 1)
#if defined (__MWERKS__) && defined (PLUGIN_GLOBALS)
#define SetupA4 long lOldA4 = SetCurrentA4 ();
#define TearDownA4 SetA4 (lOldA4);
#define UnloadSegs UnloadSegsFunc ();
static void UnloadSegsFunc ();
#else
#define SetupA4
#define TearDownA4
#define UnloadSegs
#endif //__MWERKS__
typedef struct {
const ArrangeCallbackTbl* calls;
} myprefs;
class Plugin
{
public:
Plugin(const ArrangeCallbackTbl* theCalls);
~Plugin();
arHookResult ClickNotify( arClickLocation loc, Point where, Short modifiers,
Short clickCount, arNoteID note, arFieldID field,
arPathID path );
arHookResult KeyNotify ( Short theChar, Short key, Short modifiers );
arHookResult MenuNotify ( Integer commandCode, Integer commandParam,
Short modifiers );
void AboutToMenu();
arHookResult FieldNotify( arNoteID note, arFieldID field, arFieldAction action,
const char* choiceText );
void TopicNotify( arTopicID newTopic, arWindowID newWindow,
arTopicAction action );
void TickNotify ( );
arHookResult FileNotify ( arFileAction action );
arHookResult QuitNotify ( );
void ATMNotify ( );
void FormatTheNotes ( );
private:
const ArrangeCallbackTbl* calls; // callback table
myprefs theprefs;
}; // Plugin
/*************************************************************************/
/**************************** Main entry point ***************************/
/*************************************************************************/
/* Root entry point for the module - must be the first function in the
* file, so that the linker will place it first in the code segment.
* This is the routine which Arrange calls at application startup time
* (and again at quit time).
*
* Most plug-ins will not need to modify this routine or the Hook functions
* immediately following. All customization can be done in the "Plugin"
* section (below).
*/
extern "C" Integer main( ModuleParamBlock *pb, pModuleRootAction action,
Integer /*p1*/ )
{
SetupA4;
Integer lResult = 0;
/* Extract the callback table from our parameter block, and coerce it
* to the extended Arrange table.
*/
ArrangeCallbackTbl* calls = (ArrangeCallbackTbl*)(pb->calls);
Assert (sizeof (Byte) == 1);
Assert (sizeof (Short) == 2);
Assert (sizeof (Integer) == 4);
Assert (sizeof (Float) == 8);
switch (action)
{
case mrLoad:
{
// Allocate memory and create a new Plugin object.
void* storage = calls->mem->AllocMem( sizeof(Plugin),
amFreeStore | amErrIfNoMem );
pb->moduleRefcon = uInteger(new(storage) Plugin(calls));
lResult = 1;
}
break;
case mrUnload:
{
/* Dispose of the Plugin object and release the memory
* it occupies.
*/
delete (Plugin*)(pb->moduleRefcon);
calls->mem->DeallocMem((void*)(pb->moduleRefcon), amFreeStore);
lResult = 0;
}
break;
case mrFindEntry:
default:
{
/* This module contains no extended entry points, so we always
* return 0 for the mrFindEntry message. Most plug-ins will not
* use extended entry points.
*/
lResult = 0;
}
break;
} // switch (action)
TearDownA4;
return lResult;
} // main
#if defined (__MWERKS__) && defined (PLUGIN_GLOBALS)
#pragma segment PluginLib
static void PluginLibSeg (void)
{
}
#pragma segment Main
static void UnloadSegsFunc ()
{
// Put segment unloading code here.
// Do NOT use UnloadSeg!
//UnloadA4Seg (PluginLibSeg);
}
#endif //__MWERKS__ && PLUGIN_GLOBALS
/* These hook functions simply pass control to the appropriate function
* in the Plugin object.
*/
static arHookResult OurClickHook( ModuleParamBlock* pb, arClickLocation loc,
Point where, pShort modifiers, pShort clickCount,
arNoteID note, arFieldID field,
arPathID path ENDP )
{
SetupA4;
arHookResult eResult = ((Plugin*)(pb->moduleRefcon))->ClickNotify( loc, where, modifiers,
clickCount, note, field,
path );
TearDownA4;
return eResult;
}
static arHookResult OurKeyHook( ModuleParamBlock* pb, pShort theChar, pShort key,
pShort modifiers ENDP )
{
SetupA4;
arHookResult eResult = ((Plugin*)(pb->moduleRefcon))->KeyNotify(theChar, key, modifiers);
TearDownA4;
return eResult;
}
static arHookResult OurMenuHook( ModuleParamBlock* pb, Integer commandCode,
Integer commandParam, pShort modifiers ENDP )
{
SetupA4;
arHookResult eResult = ((Plugin*)(pb->moduleRefcon))->MenuNotify( commandCode, commandParam,
modifiers );
TearDownA4;
return eResult;
}
void OurATMHook(ModuleParamBlock* pb)
{
((Plugin*)(pb->moduleRefcon))->AboutToMenu();
} // OurATMHook
static arHookResult OurFieldHook( ModuleParamBlock* pb, arNoteID note,
arFieldID field, arFieldAction action,
const char* choiceText ENDP )
{
SetupA4;
arHookResult eResult = ((Plugin*)(pb->moduleRefcon))->FieldNotify( note, field, action,
choiceText );
TearDownA4;
return eResult;
}
static void OurTopicHook( ModuleParamBlock* pb, arTopicID newTopic,
arWindowID newWindow, arTopicAction action ENDP )
{
SetupA4;
((Plugin*)(pb->moduleRefcon))->TopicNotify(newTopic, newWindow, action);
TearDownA4;
}
static void OurTickHook(ModuleParamBlock* pb ENDP)
{
SetupA4;
((Plugin*)(pb->moduleRefcon))->TickNotify();
TearDownA4;
}
static arHookResult OurFileHook(ModuleParamBlock* pb, arFileAction action ENDP)
{
SetupA4;
arHookResult eResult = ((Plugin*)(pb->moduleRefcon))->FileNotify(action);
TearDownA4;
return eResult;
}
static arHookResult OurQuitHook(ModuleParamBlock* pb ENDP)
{
SetupA4;
arHookResult eResult = ((Plugin*)(pb->moduleRefcon))->QuitNotify();
TearDownA4;
return eResult;
}
/*************************************************************************/
/********************************* Plugin ********************************/
/*************************************************************************/
/* Construct a Plugin object. This is called once, from the OurModuleRoot
* function, when the module is initialized (i.e. at application startup time).
*/
Plugin::Plugin(const ArrangeCallbackTbl* theCalls)
{
short thelength;
arDocumentPtr theCurDoc;
arDocumentPtr thePrefDoc;
Str255 ourname;
Handle temph;
// Record the callback table for future use.
calls = theCalls;
/* These commands, if un-commented-out, register this plugin to be called
* by Arrange when various events occur. For example, if you un-comment-out
* the call to SetClickHook, then Plugin::ClickNotify will be called
* whenever the user clicks in any of the locations described in the
* arClickLocation enum.
*/
// calls->ui->SetClickHook(OurClickHook, 0, true);
// calls->ui->SetKeyHook (OurKeyHook, 0, true, charFilter, keyFilter, modFilter);
// calls->ui->SetMenuHook (OurMenuHook, 0, true, whichCommand);
// calls->ui->SetFieldHook(OurFieldHook, 0, true, whichField);
//calls->ui->SetTopicHook(OurTopicHook, 0, true);
// calls->ui->SetFileHook (OurFileHook, 0, true);
//calls->ui->SetQuitHook (OurQuitHook, 0, true);
calls->ui->SetTickHook (OurTickHook, 0, true);
calls->ui->SetATMHook (OurATMHook, 0, true);
// Add an item to the About Plugins menu for this plugin.
temph = GetResource('STR ', ModuleRsrcID+1); // "About Protect"
BlockMove ((Ptr)*temph, (Ptr)(&ourname), 50);
ourname[ourname[0]+1] = 0; //Make good for C String
calls->ui->AddMenuItem(mPluginAbout, (char *)(&ourname[1]), 0, aboutCmdCode, 1);
temph = GetResource('STR ', ModuleRsrcID+2); // "Protect Text"
BlockMove ((Ptr)*temph, (Ptr)(&ourname), 50);
ourname[ourname[0]+1] = 0; //Make good for C String
calls->ui->AddMenuItem(mEdit, (char *)(&ourname[1]), 0, reformatText, 2);
calls->ui->SetMenuHook(OurMenuHook, 1, true, aboutCmdCode);
calls->ui->SetMenuHook(OurMenuHook, 2, true, reformatText);
} // Plugin constructor
/* Dispose of a Plugin object. This is called when Arrange terminates. You
* should free up any data structures which you allocation in the Plugin
* constructor (above).
*/
Plugin::~Plugin()
{
} // ~Plugin
/* This function is called whenever the user clicks in an "interesting place"
* in a document window. It should return true if we handle the click, false
* (the normal case) when the click should be passed along to other plug-ins
* or to Arrange's normal event processing. See the documentation for
* SetClickHook for more details.
*/
arHookResult Plugin::ClickNotify( arClickLocation loc, Point where,
Short modifiers, Short clickCount,
arNoteID note, arFieldID field,
arPathID path )
{
return false; // Let Arrange handle the event
} // ClickNotify
/* This function is called whenever the user types a key which matches the
* filters we pass to SetKeyHook in Plugin's constructor. It should return
* true if we handle the event, false (the normal case) when the event
* should be passed along to other plug-ins or to Arrange's normal event
* processing. See the documentation for SetKeyHook for more details.
*/
arHookResult Plugin::KeyNotify(Short theChar, Short key, Short modifiers)
{
return false; // Let Arrange handle the event
} // KeyNotify
// OK, we get the notes, get their text, and do cool stuff with them!
static Boolean ProtectText(const ArrangeCallbackTbl* calls, Ptr theptr, short* thelength)
{
Ptr p;
char lastChar=0;
char thechar=0xff;
char x;
char key[256];
calls->dlg->PromptForString("Enter password", key, 255, false);
short l = *thelength;
p=theptr;
Boolean IsChanged = false;
while (l-- > 0)
{
if (*p >= 'A' && *p <= 'Z')
{
x = (*p - 'A');
x = (x + 13) % 26;
*p = 'A' + (x);
IsChanged = true;
}
if (*p >= 'a' && *p <= 'z')
{
x = (*p - 'a');
x = (x + 13) % 26;
*p = 'a' + (x);
IsChanged = true;
}
p++;
}
return IsChanged;
}
void Plugin::FormatTheNotes ( )
{
Integer i;
short whichnote;
// Determine whether there is a selection and how many notes it contains.
Integer selCount;
arNoteID selNote;
arNoteID parentNote;
arFieldID selField;
Integer selStart;
Integer selEnd;
short thecount;
arFieldID theField;
arFieldInfo info;
arNoteInfo thetopicinfo;
short thelength;
Str255 tempstr;
Ptr theptr;
char TheName[32]="Protecting";
Boolean firstchange = true;
Str31 promptstr = "Now protecting";
Handle temph;
temph = GetResource('STR ', ModuleRsrcID+3); // "Now Reformatting Text"
BlockMove((Ptr)*temph, &promptstr, 32);
promptstr[promptstr[0]+1] = 0;
calls->dlg->DisplayNotify( (const char*)&promptstr[1], nfShowImmediately);
if (!calls->sel->FlushSelection(false))
{
calls->dlg->ClearNotify();
return;
}
switch (calls->sel->GetSelection(&selNote, &selField, &selStart, &selEnd))
{
case stNote:
case stFieldContents:
selCount = 1;
break;
case stMultipleNotes:
case stMultipleFields:
selCount = selStart;
break;
case stField:
thelength = calls->data->GetFieldTextLen(selNote, selField);
if (thelength)
{
info.versNum = 1;
calls->sysObj->GetFieldInfo(selField, &info);
thelength = calls->data->GetFieldTextLen(selNote, selField);
if (thelength)
{
theptr = NewPtr(thelength+1);
if (!theptr)
{
calls->dlg->ClearNotify();
return;
}
thelength = calls->data->GetFieldText(selNote, selField, thelength+1, (char*)theptr);
if (ProtectText(calls, theptr, &thelength))
{
if (firstchange)
{
calls->doc->SetupUndo(TheName, true);
firstchange = false;
}
calls->data->SetFieldText(selNote, selField, (char*)theptr, thelength, 0);
calls->sel->FlushSelection(false);
}
DisposePtr(theptr);
}
}
calls->dlg->ClearNotify();
return;
break;
case stText: // selected text is treated specially
thelength = calls->data->GetFieldTextLen(selNote, selField);
if (thelength)
{
theptr = NewPtr(thelength+1);
if (!theptr)
{
calls->dlg->ClearNotify();
return;
}
thelength = calls->sel->GetSelText(thelength+1, (char*)theptr, &selStart, &selEnd);
thelength = selEnd-selStart;
*((Ptr)(theptr+selEnd+1)) = 0;
if (ProtectText(calls, (Ptr)(theptr+selStart), &thelength))
{
calls->sel->ReplaceSelText((Ptr)(theptr+selStart), TheName);
calls->sel->FlushSelection(false);
}
DisposePtr(theptr);
}
calls->dlg->ClearNotify();
return;
break;
default:
calls->dlg->ClearNotify();
return;
} // switch (GetSelection result)
// Iterate over each selected note.
for (whichnote=0; whichnote<selCount; whichnote++)
{
calls->sel->GetSelEntry(whichnote, &selNote, &selField, &parentNote);
if (selNote != nil)
{
calls->notes->GetNoteInfo(selNote, &thetopicinfo);
thecount = calls->notes->CountNoteFields(selNote);
for (i=0; i<thecount; i++)
{
theField = calls->notes->GetNoteField(selNote, i);
if (theField!=nil)
{
info.versNum = 1;
calls->sysObj->GetFieldInfo(theField, &info);
if (info.type==arFTText)
{
thelength = calls->data->GetFieldTextLen(selNote, theField);
if (thelength)
{
theptr = NewPtr(thelength+1);
if (!theptr)
{
calls->dlg->ClearNotify();
return;
}
thelength = calls->data->GetFieldText(selNote, theField, thelength+1, (char*)theptr);
if (ProtectText(calls, theptr, &thelength))
{
if (firstchange)
{
calls->doc->SetupUndo(TheName, true);
firstchange = false;
}
calls->data->SetFieldText(selNote, theField, (char*)theptr, thelength, 0);
calls->sel->FlushSelection(false);
}
DisposePtr(theptr);
}
}
}
}
}
} // whichnote loop
calls->dlg->ClearNotify();
return;
}
/* This function is called whenever the user clicks in the menu bar or types
* a command key, just before processing the event. It does any fixing up
* of menus which might be necessary based on the current state of affairs.
*/
void Plugin::AboutToMenu()
{
arNoteID selNote;
arFieldID selField;
Integer selStart,selEnd;
arSelType selType = calls->sel->GetSelection( &selNote, &selField,
&selStart, &selEnd );
Boolean hasSingleSel = ( selType == stNote || selType == stMultipleNotes || selType == stText || selType == stField );
calls->ui->SetMenuItem(mEdit, reformatText, 2, nil, ((selType == stNote) || (selType == stMultipleNotes) || (selType == stText) || (selType == stField)), 0, 0);
}
arHookResult Plugin::MenuNotify( Integer commandCode, Integer commandParam,
Short modifiers )
{
ProcessSerialNumber thepsn;
arTopicID thistopic;
arTopicInfo topicinfo;
/* If this is our About menu item, display our about-box dialog and return
* true to indicate we handled the command.
*/
if (commandCode == aboutCmdCode)
{
Alert(ModuleRsrcID, nil);
return true;
}
if (commandCode == reformatText)
{
FormatTheNotes();
return true;
}
return false; // Let Arrange handle the event
} // MenuNotify
/* If we register to recieve events for a field by calling SetFieldHook, this
* function will be called for any events in that field. It should return
* false in almost all cases. See the documentation for SetFieldHook for
* more details.
*/
arHookResult Plugin::FieldNotify( arNoteID note, arFieldID field,
arFieldAction action, const char* choiceText )
{
return false;
} // FieldNotify
/* This function is called whenever the user switches windows or changes
* the current folder/topic/view in the front window. See the documentation
* for SetTopicHook for more details.
*/
void Plugin::TopicNotify( arTopicID newTopic, arWindowID newWindow,
arTopicAction action )
{
} // TopicNotify
/* This function is called periodically, whenever Arrange recieves a null
* event from the Event Manager.
*/
void Plugin::TickNotify()
{
} // TickNotify
/* This function is called whenever various file-level events occur. It
* should return true in almost all cases. See the documentation for
* SetFileHook for more details.
*/
arHookResult Plugin::FileNotify(arFileAction action)
{
return true;
} // FileNotify
/* This function is called if the user voluntarily quits Arrange. It should
* return true to allow the user to quit, false to prevent it. See the
* documentation for SetQuitHook for more details.
*/
arHookResult Plugin::QuitNotify()
{
return true;
} // QuitNotify
/* This function is called whenever the user clicks in the menu bar or types
* a command key, just before processing the event. It should do any fixing
* up of menus which might be necessary based on the current state of affairs.
* See the documentation for SetATMHook for more details.
*/
void Plugin::ATMNotify()
{
} // ATMNotify